package xde2d.parser
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.Endian;
	
	import away3d.core.base.CompactSubGeometry;
	import away3d.core.base.Geometry;
	import away3d.entities.Mesh;
	import away3d.events.AssetEvent;
	import away3d.loaders.parsers.ParserBase;
	import away3d.materials.TextureMaterial;
	import away3d.utils.Cast;
	
	/**
	 *  @author:Gaara
	 *  2013-3-4
	 *  mod模型解析器
	 **/
	public class ModPacketParser extends BinaryParser
	{
		
		private static const MOD_TOKEN_FILEHEADER:uint = 16;//文件头
		private static const MOD_TOKEN_FILEITEM:uint = 17;//文件块
		private static const MOD_VERSION:uint = 0x1000;//mod版本
		
		private static const FILE_TYPE_PNG:uint = 65537;
		private static const FILE_TYPE_JPG:uint = 65538;//图片块
		
		private static const FILE_TYPE_XMESH:uint = 65539;//xmesh块 
		private static const FILE_TYPE_XANIM:uint = 65540;//xanim块
		
		/** 文件头 **/
		private var _fileHead:ModFileHead;
		
		/** 模型块 **/
		private var _chunk:ModChunk;
		
		/** loader字典 **/
		private var _imageLoaderDic:Dictionary;
		
		/** 几何图形 **/
		private var _geometry:Geometry;
		
		/** 图片字典 **/
		private var _BitmapDataDic:Dictionary;
		
		/** xmesh解析 **/
		private var _xmeshParser:XMeshParser;
		
		/** mesh **/
		private var _mesh:Mesh;		
		
		/**
		 * 指定资源的扩展名
		 */
		public static function supportsType(extension : String) : Boolean
		{
			extension = extension.toLowerCase();
			return extension == "mod";
		}
		
		override protected function proceedParsing():Boolean
		{
			if(!_startedParsing) {
				byteData.endian = Endian.LITTLE_ENDIAN;
				_startedParsing = true;
			}
			
			if(_reachedEOF){
				if(this._geometry && !_imageLoaderDic){
					_mesh = new Mesh(this._geometry);
					var material:TextureMaterial;
					var subGeo:CompactSubGeometry;
					for (var i:int = 0; i < this._geometry.subGeometries.length; i++) 
					{
						subGeo = this._geometry.subGeometries[i];
						material = new TextureMaterial(Cast.bitmapTexture(_BitmapDataDic[subGeo.materialName]))
						material.alphaBlending = true;
						_mesh.subMeshes[i].material = material;
					}
					
					finalizeAsset(_mesh);
					return PARSING_DONE;
				}
			}
			//类型
			var token:uint;
			while(hasTime())
			{
				token = getNextInt();
				switch(token)
				{
					case MOD_TOKEN_FILEHEADER:
						this._fileHead = new ModFileHead;
						this._fileHead.version = getNextInt();
						this._fileHead.filecount = getNextInt();
						trace("num:"+_fileHead.filecount);
						if(this._fileHead.version != MOD_VERSION){
							throw (new Error("Unknown version number encountered!"));
						}
						break;
					case MOD_TOKEN_FILEITEM:
						this._chunk = _chunk || new ModChunk();
						_chunk.type = getNextInt();
						_chunk.name = getNextString();
						_chunk.len = getNextInt();
						//解析块
						this.parseChunk();
						break
					default:
						if (!this._reachedEOF){
							sendUnknownKeywordError();
						}
				}
				
				this._reachedEOF = (byteData.bytesAvailable == 0);
				return ParserBase.MORE_TO_PARSE;
			}
			
			return ParserBase.MORE_TO_PARSE;
		}
		
		/**
		 *  功能:解析块
		 *  参数:
		 **/
		private function parseChunk():void
		{
			if (byteData.bytesAvailable < this._chunk.len){
				sendParseError("可读长度小于块长度");
			}
			
			var imgLoader:ImageLoader;
			
			var tempByteArray:ByteArray = new ByteArray;
			byteData.readBytes(tempByteArray,0,this._chunk.len);
			
			if(_chunk.type == FILE_TYPE_PNG || _chunk.type == FILE_TYPE_JPG){
				imgLoader = new ImageLoader;
				imgLoader.loader = new Loader;
				imgLoader.name = _chunk.name;
				
				_imageLoaderDic = _imageLoaderDic || new Dictionary();
				
				_imageLoaderDic[imgLoader.name] = imgLoader;
				imgLoader.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.onImageLoadComplete);
				imgLoader.loader.loadBytes(tempByteArray);
			}
			else if(_chunk.type == FILE_TYPE_XMESH){
				trace("xmesh");
				_xmeshParser = new XMeshParser;
				//				_xmeshParser._url =  _chunk.name;
				_xmeshParser.isModeFile = true;
				_xmeshParser.addEventListener(AssetEvent.GEOMETRY_COMPLETE, this.onGeometryComplete);
				_xmeshParser.parseAsync(tempByteArray);
			}
			else if(_chunk.type == FILE_TYPE_XANIM){
				trace("XANIM");
			}
		}
		
		/** 图片加载完成 **/
		private function onImageLoadComplete(evt:Event):void{
			var loader:Loader = (evt.target as LoaderInfo).loader;
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, this.onImageLoadComplete);
			
			var bmd:BitmapData  = (loader.content as Bitmap).bitmapData;
			
			var imageLoader:ImageLoader
			for each (imageLoader in _imageLoaderDic) 
			{
				if(imageLoader.loader != loader) continue
				
				_BitmapDataDic = _BitmapDataDic || new Dictionary;
				
				_BitmapDataDic[imageLoader.name] = bmd;
				delete _imageLoaderDic[imageLoader.name];
			}
			
			var keyCount:int;
			
			for each (imageLoader in _imageLoaderDic) 
			{
				keyCount++;
			}
			
			if(keyCount == 0){
				_imageLoaderDic = null;
			}
			
		}
		
		/** geometry 加载完成 **/
		private function onGeometryComplete(asset:AssetEvent):void{
			this._xmeshParser.removeEventListener(AssetEvent.GEOMETRY_COMPLETE, this.onGeometryComplete);
			this._geometry = (asset.asset as Geometry);
		}
	}
}
import flash.display.Loader;

/**
 *  文件头
 **/
class ModFileHead {
	public var version:int;
	public var filecount:int;
}

/**
 *  模型块
 **/
class ModChunk {
	public var type:int;
	public var len:int;
	public var name:String;
}

/**
 *  图片块加载器
 **/
class ImageLoader {
	public var loader:Loader;
	public var name:String;
}